const fs = require('fs');
const path = require('path');
const parser = require('@babel/parser');
const traverse = require('@babel/traverse').default;
const t = require('@babel/types');
const generator = require('@babel/generator').default;
const fse = require('fs-extra');

// 读取命令行传入的目录路径
const dirPath = process.argv[2];
if (!dirPath) {
    console.error('Usage: node rename_functions.js <path_to_directory>');
    process.exit(1);
}

// 生成新的目录路径
const newDirPath = path.join(path.dirname(dirPath), `${path.basename(dirPath)}_modified`);

function convertToValidFunctionName(str) {
  // 正则表达式匹配非字母、数字、下划线和美元符号的字符
  const illegalChars = /[^a-zA-Z0-9_$]/g;
  // 如果字符串以数字开头，则在前面加上一个下划线
  if (/^\d/.test(str)) {
    str = '_' + str;
  }
  // 替换非法字符为下划线
  return str.replace(illegalChars, '_');
}

// 生成唯一的函数名
function generateUniqueName(filePath, counter) {
    const basename = path.basename(filePath);
    // 获取文件扩展名
    const extname = path.extname(basename);
    // 去掉扩展名得到文件名
    const filenameWithoutExt = basename.slice(0, -extname.length);
    const validFuncName = convertToValidFunctionName(filenameWithoutExt);
    return `${validFuncName}_${counter}`;
}

// 递归处理目录中的所有.js和.ts文件
function processDirectory(directory) {
    fs.readdir(directory, { withFileTypes: true }, (err, files) => {
        if (err) {
            console.error(`Error reading directory ${directory}: ${err}`);
            return;
        }

        files.forEach(file => {
            const filePath = path.join(directory, file.name);
            if (file.isDirectory()) {
                processDirectory(filePath);
            } else if (file.isFile() && (file.name.endsWith('.js') || file.name.endsWith('.ts'))) {
                processFile(filePath);
            }
        });
    });
}

// 处理单个文件
function processFile(filePath) {
    // 用于生成唯一函数名的计数器
    let counter = 0;
    fs.readFile(filePath, 'utf-8', (err, code) => {
        if (err) {
            console.error(`Error reading file ${filePath}: ${err}`);
            return;
        }

        // 解析代码生成AST
        const ast = parser.parse(code, {
            sourceType: 'module',
            plugins: ['typescript', 'jsx']
        });

        // 统计匿名FunctionExpression的次数
        let anonymousFunctionCount = 0;

        traverse(ast, {
            enter(path) {
                if (path.node.type === 'FunctionExpression' && !path.node.id) {
                    anonymousFunctionCount++;
                }
            }
        });

        // 如果匿名FunctionExpression的次数为0，不做任何处理
        if (anonymousFunctionCount === 0) {
            return;
        }

        // 重新遍历AST，为匿名FunctionExpression赋予新的唯一名字
        traverse(ast, {
            enter(path) {
                if (path.node.type === 'FunctionExpression' && !path.node.id) {
                    const uniqueFuncName = generateUniqueName(filePath, counter++);
                    path.node.id = t.identifier(uniqueFuncName);
                }
            }
        });

        // 生成新的代码
        const { code: newCode } = generator(ast);

        // 替换源文件
        const newFilePath = path.join(newDirPath, path.relative(dirPath, filePath));
        fse.ensureDir(path.dirname(newFilePath), (err) => {
            if (err) {
                console.error(`Error creating directory for ${newFilePath}: ${err}`);
                return;
            }
            fs.writeFile(newFilePath, newCode, 'utf-8', (err) => {
                if (err) {
                    console.error(`Error writing file ${newFilePath}: ${err}`);
                    return;
                }
                console.log(`Processed file: ${newFilePath}; anonymousFunctionCount: ${anonymousFunctionCount}`);
            });
        });
    });
}

// 复制目录
fse.copy(dirPath, newDirPath, (err) => {
    if (err) {
        console.error(`Error copying directory ${dirPath} to ${newDirPath}: ${err}`);
        return;
    }
    console.log(`Directory copied to ${newDirPath}`);
    // 开始处理目录
    processDirectory(newDirPath);
});